using System;
using System.Globalization;
using GammaJul.ReSharper.GammaXaml.Highlightings.Xaml;
using GammaJul.ReSharper.GammaXaml.Psi;
using JetBrains.Annotations;
using JetBrains.Application.Progress;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Psi.Parsing;
using JetBrains.ReSharper.Psi.Xaml;
using JetBrains.ReSharper.Psi.Xml.Tree;
using JetBrains.Text;
using JetBrains.TextControl;

namespace GammaJul.ReSharper.GammaXaml.QuickFixes.Xaml {

	/// <summary>
	/// Bulb item that changes a Grid.RowSpan or Grid.ColumnSpan value.
	/// </summary>
	public class UseSpanItem : BulbActionBase {
		private readonly GridSpanValueOutOfRangeHighlighting _highlighting;
		private readonly int _spanValue;

		public int SpanValue {
			get { return _spanValue; }
		}
		
		public override string Text {
			get {
				string defName = _highlighting.DefinitionType.ToString().ToLowerInvariant();
				string formatString;
				switch (_spanValue) {
					case 1:
						formatString = "Span only " + defName + " {0}";
						break;
					case 2:
						formatString = "Span " + defName + "s {0} and {1}";
						break;
					default:
						formatString = "Span " + defName + "s {0} to {1}";
						break;
				}
				int firstColumn = _highlighting.DefinitionValue;
				int lastColumn = firstColumn + _spanValue - 1;
				return String.Format(CultureInfo.CurrentCulture, formatString, firstColumn, lastColumn);
			}
		}
		
		protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) {
			IXmlToken valueToken = _highlighting.ValueToken;
			var newToken = XmlTokenTypes.GetInstance<XamlLanguage>().TEXT.Create(new StringBuffer(_spanValue.ToString(CultureInfo.InvariantCulture)));
			valueToken = (IXmlToken) valueToken.ReplaceBy(newToken);
			valueToken.GetPsiServices().MarkAsDirty(valueToken.GetSourceFile());

			return null;
		}

		public UseSpanItem([NotNull] GridSpanValueOutOfRangeHighlighting highlighting, int spanValue) {
			if (highlighting == null)
				throw new ArgumentNullException("highlighting");

			_highlighting = highlighting;
			_spanValue = spanValue;
		}
	}

}